package server;

import pojo.*;
import util.PokeComparator;
import util.StreamUtil;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Server {
    //服务器socket
    private ServerSocket serverSocket;
    //当前连接的总用户数
    private int peopleNumber = 0;
    //当前用户编号
    private int id;
    //当前所有用户的信息
    private List<Person> people;
    //当前正在进行的游戏局数
    private int gameNumber = 0;
    //当前所有用户的socket的输入输出流
    private List<ObjectOutputStream> outputStreamList;
    private List<ObjectInputStream> inputStreamList;
    private StreamUtil<ServerMessage,ClientMessage> streamUtil;

    public Server() throws IOException, InterruptedException, ClassNotFoundException {
        people = new ArrayList<>();
        serverSocket = new ServerSocket(10086);
        System.out.println("### 服务器完成初始化，等待玩家连接 ###");
        outputStreamList = new ArrayList<>();
        inputStreamList = new ArrayList<>();
        streamUtil = new StreamUtil<>(ClientMessage.class);
        //创建匿名线程来接受用户连接请求，最多5个用户连线
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    try {
                        Socket socket = serverSocket.accept();
                        System.out.println("### 有新玩家连接 ###");
                        ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
                        ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
                        outputStreamList.add(outputStream);
                        inputStreamList.add(inputStream);
                        if (peopleNumber >= 5){
                            //当在线人数大于等于5时，拒绝新用户连接
                            ServerMessage serverMessage = new ServerMessage();
                            serverMessage.setType(ServerInstruction.REJECT);
                            streamUtil.write(outputStream,serverMessage);
                        }else {
                            //初始化玩家
                            ClientMessage clientMessage = streamUtil.read(inputStream);
                            Person person = new Person();
                            person.setId(id);
                            person.setName(clientMessage.getName());
                            people.add(person);
                            peopleNumber++;
                            id++;
                        }
                    } catch (IOException | ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();


        while(true){
            //只有两个用户及以上才可开始游戏，每3秒会提示一次人数不足
            if (people.size() < 2){
                Thread.sleep(3000);
                System.out.println("### 人数不足，无法开始游戏 ###");
                continue;
            }
            System.out.println("### 开始一局新游戏，等待玩家准备 ###");
            //初始化一局新的游戏
            gameNumber++;
            //让所有人准备游戏
            checkReady();

            List<ObjectInputStream> inputList = new ArrayList<>();
            inputList.addAll(inputStreamList);
            List<ObjectOutputStream> outputList = new ArrayList<>();
            outputList.addAll(outputStreamList);
            GameController gameController = new GameController(outputList,inputStreamList,gameNumber,people.size(),people);

            System.out.println("### 所有玩家准备完成，游戏开始 ###");
            System.out.println("### 当前游戏编号为:"+gameNumber+" ###");
            //游戏开始，进行发牌和下注
            int winnerIndex = gameController.gameBegin();
            //通知玩家游戏结束，并说明获胜者是谁
            gameController.notifyWinner(winnerIndex);
            //进行游戏结算
            gameController.gameAccount(winnerIndex);

            System.out.println("##################GAME OVER############################");
            System.out.println("##################"+winnerIndex+"号玩家获胜"+"############################");
            System.out.println();
        }
    }

    /**
     * 让所有人准备游戏
     */
    private void checkReady() throws InterruptedException, ClassNotFoundException, IOException {

        boolean ready = false;
        //循环直到所有人已经准备好了才结束循环。放在循环里面
        while( !ready ){
            Thread.sleep(2000);

            for (int i=0;i<people.size();i++){
                if (people.get(i).isReceivedReadyMessage()){
                    continue;
                }

                //开一个线程来接受用户的准备请求
                int finalI = i;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            streamUtil.read(inputStreamList.get(finalI));
                        } catch (IOException | ClassNotFoundException e) {
                            e.printStackTrace();
                        }
                        people.get(finalI).setReady(true);
                    }
                }).start();

                //发送准备准备游戏的命令
                ServerMessage serverMessage = new ServerMessage();
                serverMessage.setType(ServerInstruction.READY);
                serverMessage.setMoneyLeft(people.get(i).getMoney());
                if (people.get(i).getMoney() == 0){
                    //发现玩家金额为0时，自动为其充值1000元
                    people.get(i).addMoney(1000);
                }
                streamUtil.write(outputStreamList.get(i),serverMessage);
                people.get(i).setReceivedReadyMessage(true);

            }

            //所有玩家都已经准备好了，循环才结束
            ready = true;
            for (Person gamer : people) {
                if (!gamer.isReady()){
                    ready = false;
                }
            }
        }
    }
}
